package com.angel.email.connection;

import java.util.ArrayList;
import java.util.List;

import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;

import org.apache.log4j.Logger;

import com.angel.email.attachments.manager.EmailAttachmentManager;
import com.angel.email.dtos.FolderDTO;
import com.angel.email.exceptions.EmailAccessException;

/**
 *
 * @author William
 *
 */
public abstract class EmailConnection {

	private static final Logger LOGGER = Logger.getLogger(EmailConnection.class);

	private List<Folder> folders;
	private Store store;
	private String name;
	private EmailAttachmentManager emailAttachmentManager;

	public EmailConnection(Store store, String name){
		super();
		this.setStore(store);
		this.setFolders(new ArrayList<Folder>());
		this.setEmailAttachmentManager(new EmailAttachmentManager());
	}

	/**
	 * @return the folders
	 */
	public List<Folder> getFolders() {
		return folders;
	}

	/**
	 * @param folders the folders to set
	 */
	protected void setFolders(List<Folder> folders) {
		this.folders = folders;
	}

	/**
	 * @return the store
	 */
	public Store getStore() {
		return store;
	}

	/**
	 * @param store the store to set
	 */
	public void setStore(Store store) {
		this.store = store;
	}

	public FolderDTO getFolderFor(String folderName){
		Folder folder = this.getFolder(folderName);
		return new FolderDTO(folder);
	}

	private Folder findFolderOpened(String folderName){
		for(Folder f: folders) {
			if(f.getName().equalsIgnoreCase(folderName)){
				return f;
			}
		}
		return null;
	}

	protected Folder getFolder(String folderName){
		Folder folder = this.findFolderOpened(folderName);
		if(folder == null){
			folder = this.findFolder(folderName);
			this.getFolders().add(folder);
		}
		return folder;
	}

	private Folder findFolder(String folderName){
		Folder folder = null;
		try {
			folder = store.getFolder(folderName);
			if(!folder.isOpen()){
				folder.open(Folder.READ_ONLY);
			}
		} catch (MessagingException e) {
			throw new EmailAccessException("Error getting / openning email folder [" + folderName + "].", e);
		}
		return folder;
	}

	public void closeConnection(){
		this.closeFolderConnection();
		this.closeStoreConnection();
	}

	protected void closeStoreConnection() {
		if(this.getStore().isConnected()){
			try {
				this.getStore().close();
			} catch (MessagingException e) {
				throw new EmailAccessException("Cannot close connection for email store.",e);
			}
		}

	}

	protected void closeFolderConnection(){
		for(Folder f: this.getFolders()){
			try {
				if(f.isOpen()){
					f.close(Boolean.FALSE.booleanValue());
				}
			} catch (MessagingException e) {
				getLogger().warn("Error closing folder [" + f.getName() + "] caused by: " + e.getCause());
			}
		}
		this.getFolders().clear();
	}

	protected static Logger getLogger(){
		return LOGGER;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	protected void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the emailAttachmentManager
	 */
	protected EmailAttachmentManager getEmailAttachmentManager() {
		return emailAttachmentManager;
	}

	/**
	 * @param emailAttachmentManager the emailAttachmentManager to set
	 */
	protected void setEmailAttachmentManager(
			EmailAttachmentManager emailAttachmentManager) {
		this.emailAttachmentManager = emailAttachmentManager;
	}
}
